﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.ServiceModel;
using System.ServiceProcess;
using System.Configuration;
using System.Runtime.Serialization;
using System.Xml;
using System.Text;
using System.Linq;
using MySQL.Db;
//using MySql.Data.MySqlClient;
using NLog;

namespace Gollie.Mail
{
	[DataContract]
	public class EMail
	{
		private static readonly Logger logger = LogManager.GetCurrentClassLogger();

		//TODO: set to null on publish
		//private const string testHost = "http://localhost:4395";

		private string name;
		Dictionary<string, string> args;

		private string recipients;
		protected string subject;
		private string origBody;
		protected string body;
		private string from;
		private bool bcc = false;
		private string attachmentPath = null;
		private string defaultStyle = null;
		private string regardsText = null;

		public void DoQueue()
		{
			try
			{
				logger.Debug("start Email.DoQueue...");
				this.Compose();

				this.Publish();
				logger.Debug("finished Email.DoQueue...");
			}
			catch (Exception e)
			{
				logger.DebugException("error", e);
			}
		}

		public Query DoQueueBatch()
		{
			this.Compose();

			return this.GetPublishQuery();
		}

		private void Compose()
		{
			this.Read();
			this.SetBody();
		}

		private void Publish()
		{
			this.GetPublishQuery().Execute();
		}

		private Query GetPublishQuery()
		{
			QueryArguments args = new QueryArguments();

			args.Add("p_subject", subject);
			args.Add("p_body", body);
			args.Add("p_recipient", recipients);
			args.Add("p_bcc", bcc);
			args.Add("p_attachment", attachmentPath);

			return new Query("sp_insertsinglemail", args);
		}

		private void Read()
		{
			XmlDocument doc = new XmlDocument();
			doc.Load(ConfigurationManager.AppSettings["xmlmailpath"]);

			XmlNode configNode = doc.SelectSingleNode("/*/config");
			if (configNode != null)
			{
				XmlAttribute styleAttr = configNode.Attributes["defaultstyle"];
				if (styleAttr != null)
					defaultStyle = styleAttr.Value;

				XmlNode regardsNode = configNode.SelectSingleNode("regardstext");
				if (regardsNode != null)
					this.regardsText = regardsNode.InnerXml;
			}
			
			XmlNode node = doc.SelectSingleNode("/*/mail[@name='" + this.name + "']");

			if (node != null)
			{
				this.subject = node.Attributes["subject"].Value;
				this.from = node.Attributes["from"].Value;
				XmlAttribute attr = node.Attributes["bcc"];
				if (attr != null)
					this.bcc = (attr.Value == "true");

				this.origBody = node.InnerXml;
			}
		}

		private void SetBody()
		{
			string cleaned = new string((this.origBody.Where(c => c.CompareTo(' ') >= 0)).ToArray());
			StringBuilder str = new StringBuilder(cleaned, 1024);
			StringBuilder strSubject = new StringBuilder(subject);

			if (args != null)
			{
				foreach (string key in args.Keys)
				{
					string newVal = args[key];

					if (newVal != null)
					{
						str.Replace(key, newVal);
						strSubject.Replace(key, newVal);
					}
				}
			}

			if (this.regardsText != null)
				str.Append(this.regardsText);

			//if (EMail.testHost != null)
			//	str.Replace("http://www.gollie.nl", EMail.testHost);

			if (this.defaultStyle != null)
			{
				str.Insert(0, "<div style=\"" + this.defaultStyle + "\">")
					.Append("</div>");
			}

			this.body = str.ToString();
			this.subject = strSubject.ToString();
		}

		public static bool IsEmailAddressValid(string email)
		{
			bool valid = true;

			try
			{
				System.Net.Mail.MailAddress address = new System.Net.Mail.MailAddress(email);

				int dot = address.Host.IndexOf(".");
				if (dot <= 0 || dot >= address.Host.Length - 2)
					throw new Exception("dummy");

				if (email.Contains(','))
					throw new Exception("dummy");
			}
			catch
			{
				valid = false;
			}

			return valid;
		}

		[DataMember]
		public string Name
		{
			get { return name; }
			set { name = value; }
		}

		[DataMember]
		public string Recipients
		{
			get { return recipients; }
			set { recipients = value; }
		}

		[DataMember]
		public string AttachmentPath
		{
			get { return attachmentPath; }
			set { attachmentPath = value; }
		}

		[DataMember]
		public Dictionary<string, string> Args
		{
			get { return args; }
			set { args = value; }
		}
	}
}
